#include <stdio.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <arpa/inet.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>

#define VOICE_PATH "wav/1.pcm" //
int connect_fd; //保存连接成功后与客户端通信的连接文件描述符
int sockfd;

/*
    server_init: 初始化服务器
    @ip： 服务器绑定的ip
    @port： 服务器绑定的端口
    返回值：
        成功 0
        失败 -1
*/
int server_init(char *ip, short port)
{
    //1.创建一个套接字  socket
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == sockfd)
    {
        perror("socket create fail");
        return -1;
    }

    //2. bind绑定服务器的ip及端口
    struct sockaddr_in server_addr; //定义一个ipv4专用地址结构体，用来指定要绑定的ip及端口
    server_addr.sin_family = AF_INET; //指定ipv4
    server_addr.sin_port = htons(port); //指定端口号，把端口号的主机字节序转换为网络字节序
    server_addr.sin_addr.s_addr = inet_addr(ip); //指定ip， 点分式的ip转换为网络中识别的网络字节序的ip地址
    //inet_aton("192.168.31.10", &server_addr.sin_addr);
    int ret = bind(sockfd, (struct sockaddr *)&server_addr, (socklen_t)sizeof(server_addr));
    if (-1 == ret)
    {
        perror("bind fail");
        close(sockfd);
        return -1;
    }

    //3. 监听 listen
    ret = listen(sockfd, 5);
    if (-1 == ret)
    {
        perror("listen fail");
        close(sockfd);
        return -1;
    }

    //4. 接收来自客户端的请求  accept, 得到与客户端程序连接成功后的连接套接字
    struct sockaddr_in client_addr; //结构体用来保存客户端的地址
    socklen_t client_addr_len;
    connect_fd = accept(sockfd, (struct sockaddr *)&client_addr, &client_addr_len);
    if(connect_fd == -1)
    {
        perror("accept fail");
        close(sockfd);
        return -1;
    }

    return 0;
}

/*
    save_voice_file: 保存客户端发送到服务器进行识别的语音文件
    返回值：
        成功 0
        失败 -1
*/
int save_voice_file(void)
{
    //1.打开语音文件
    int voice_fd = open(VOICE_PATH, O_RDWR | O_CREAT | O_TRUNC, 0666);
    if (-1 == voice_fd)
    {
        perror("open fail");
        return -1;
    }

    //2.接收文件的大小
    int size = 0;
    read(connect_fd, &size, 4);

    //3.接收文件的内容
    int file_size = 0;
    while(1)
    {
        char buf[128] = {0};
        int ret = read(connect_fd, &buf, sizeof(buf)); //从与客户端建立连接的连接套接字上读取到的
        if (ret == -1)
        {
            perror("read fail");
            return -1;
        }
        else if(ret > 0)
        {
            write(voice_fd, &buf, ret);
            file_size += ret;
            if(file_size >= size) //文件所有的字节接收完毕
            {
                break;
            }
        }  
        else if(ret == 0)
        {
            printf("文件已经读完\n");
            break;
        } 
    }

    //关闭文件
    close(voice_fd);
    printf("save_voice_file success!\n");
    return 0;
}
